package pro.shushi.pamirs.hr.core.service.eam;

import com.alibaba.excel.util.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pro.shushi.pamirs.core.common.FetchUtil;
import pro.shushi.pamirs.file.api.enmu.TaskMessageLevelEnum;
import pro.shushi.pamirs.framework.connectors.data.api.datasource.DsHintApi;
import pro.shushi.pamirs.framework.connectors.data.tx.transaction.Tx;
import pro.shushi.pamirs.hr.api.enums.BooleanConstantEnum;
import pro.shushi.pamirs.hr.api.enums.HrSimpleExpEnum;
import pro.shushi.pamirs.hr.api.enums.eam.*;
import pro.shushi.pamirs.hr.api.model.eam.*;
import pro.shushi.pamirs.hr.api.model.org.Employee;
import pro.shushi.pamirs.hr.api.pmodel.eam.EamUkDtMtoolProxy;
import pro.shushi.pamirs.hr.api.pmodel.eam.EamUkHdMtoolProxy;
import pro.shushi.pamirs.hr.api.service.EmployeeService;
import pro.shushi.pamirs.hr.api.service.eam.EamUkHdMtoolService;
import pro.shushi.pamirs.hr.api.tmodel.EamUkDtMtoolReq;
import pro.shushi.pamirs.hr.api.tmodel.EamUkHdMtoolReq;
import pro.shushi.pamirs.hr.api.tmodel.EmployeeBatchReq;
import pro.shushi.pamirs.hr.core.mapper.EmployeeMapper;
import pro.shushi.pamirs.hr.core.mapper.eam.EamUkHdMapper;
import pro.shushi.pamirs.hr.core.util.CustomModelUtil;
import pro.shushi.pamirs.meta.annotation.Fun;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.api.dto.common.Message;
import pro.shushi.pamirs.meta.api.dto.config.TxConfig;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.common.exception.PamirsException;
import pro.shushi.pamirs.meta.common.spring.BeanDefinitionUtils;
import pro.shushi.pamirs.meta.common.util.ListUtils;
import pro.shushi.pamirs.meta.enmu.InformationLevelEnum;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 工装保养服务类
 */
@Service
@Fun(EamUkHdMtoolService.FUN_NAMESPACE)
public class EmUkHdMtoolServiceImpl implements EamUkHdMtoolService {


    @Override
    public void beforeStartMaintain(EamUkHdMtoolReq data) {
        String modelModel = EamUkHdMtoolReq.MODEL_MODEL;
        String orgCode = data.getOrgCode();
        String ukCode = data.getUkCode();
        String mtoolCode = data.getMtoolCode();
        //校验参数orgCode,ukCode,mtoolCode不允许为空
        if(StringUtils.isBlank(orgCode)){
            //{} 不允许为空。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00001,CustomModelUtil.getFieldDisplayName(modelModel,"orgCode")).errThrow();
        }
        if(StringUtils.isBlank(ukCode)){
            //{} 不允许为空。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00001,CustomModelUtil.getFieldDisplayName(modelModel,"ukCode")).errThrow();
        }
        if(StringUtils.isBlank(mtoolCode)){
            //{} 不允许为空。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00001,CustomModelUtil.getFieldDisplayName(modelModel,"mtoolCode")).errThrow();
        }

        //校验保养单存在
        EamUkHdMtoolProxy eamUkHhRow = new EamUkHdMtoolProxy().setOrgCode(orgCode).setUkCode(ukCode).queryOne();
        if(eamUkHhRow == null){
            //保养单编码：{}在组织编码：{}中未定义。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00002,ukCode,orgCode).errThrow();
        }

        //校验工装信息存在且启用
        BsMtool mtoolRow = new BsMtool().setOrgCode(orgCode).setMtoolCode(mtoolCode).queryOne();
        if(mtoolRow == null){
            //工装编码：{}在组织编码：{}中未定义。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00004,mtoolCode,orgCode).errThrow();
        }
        if(!BooleanConstantEnum.Y.value().equals(mtoolRow.getIsValid().getValue())){
            //工装编码：{}在组织编码：{}中未启用。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00005,mtoolCode,orgCode).errThrow();
        }
        String mmdCode = mtoolRow.getMmdCode();

        //校验工装型号存在
        BsMtoolMd mdRow = new BsMtoolMd().setOrgCode(orgCode).setMmdCode(mmdCode).queryOne();
        if (mdRow == null) {
            //工装型号：{}在组织编码：{}中未定义。
            throw PamirsException.construct(EamExpEnum.MTOOLMD_NOT_EXISTS,orgCode,mmdCode).errThrow();
        }

        //校验工装信息状态以及保养单状态
        //若dsMtool.mtool_stat=1 and uk_stat<>2 or dsMtool.mtool_stat<>0 and uk_stat in(0,1)  时，报错：工装编码：{0}的状态为：{1}，不能操作
        boolean flag1 = mtoolRow.getMtoolStat().equals(MtoolStatEnum.UPKEEP) && !eamUkHhRow.getUkStat().equals(UkStatEnum.DOING);
        boolean flag2 = !mtoolRow.getMtoolStat().equals(MtoolStatEnum.NORMAL)
                && (eamUkHhRow.getUkStat().equals(UkStatEnum.UNDEAL) && eamUkHhRow.getUkStat().equals(UkStatEnum.UNKONW) );
        if(flag1 || flag2){
            //工装编码：{}的状态为：{}，不能操作
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00006,mtoolCode,mtoolRow.getMtoolStat().getDisplayName()).errThrow();
        }

        //--- 校验报废次数、天数，是否正在使用 ----忽略--

        //校验保养项目不能为空 -- 尝试自定义查询：指定数据源：https://doc.oinone.top/backend/7376.html
        EamUkHdMapper eamUkHdMapper = BeanDefinitionUtils.getBean(EamUkHdMapper.class);
        try (DsHintApi dsHintApi = DsHintApi.model(EamUkHd.MODEL_MODEL)) {
            List<Map<String, Object>> dataList = eamUkHdMapper.eamUkDtHasData(orgCode, ukCode);
            if (dataList == null || dataList.size() == 0) {
                //保养项目明细不允许为空。
                throw PamirsException.construct(EamExpEnum.EAM_ERROR_00007).errThrow();
            }
        }


    }

    @Transactional
    @Override
    public void confirmStartMaintain(EamUkHdMtoolReq data) {
        String modelModel = EamUkHdMtoolReq.MODEL_MODEL;
        String orgCode = data.getOrgCode();
        String ukCode = data.getUkCode();
        String mtoolCode = data.getMtoolCode();
        //校验参数orgCode,ukCode,mtoolCode不允许为空
        if(StringUtils.isBlank(orgCode)){
            //{} 不允许为空。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00001,CustomModelUtil.getFieldDisplayName(modelModel,"orgCode")).errThrow();
        }
        if(StringUtils.isBlank(ukCode)){
            //{} 不允许为空。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00001,CustomModelUtil.getFieldDisplayName(modelModel,"ukCode")).errThrow();
        }
        if(StringUtils.isBlank(mtoolCode)){
            //{} 不允许为空。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00001,CustomModelUtil.getFieldDisplayName(modelModel,"mtoolCode")).errThrow();
        }

        //校验保养单存在
        EamUkHdMtoolProxy eamUkHhRow = new EamUkHdMtoolProxy().setOrgCode(orgCode).setUkCode(ukCode).queryOne();

        //若状态 in (未知,未处理)或实际开始时间为空时，更新主表eam_uk_hd
        boolean flag1 = eamUkHhRow.getUkStat().equals(UkStatEnum.UNDEAL) && eamUkHhRow.getUkStat().equals(UkStatEnum.UNKONW);
        boolean flag2 = eamUkHhRow.getRkPbdate() == null;
        if(flag1 || flag2){
            eamUkHhRow.setUkStat(UkStatEnum.DOING);
            eamUkHhRow.setRkPbdate(new Date());
            eamUkHhRow.setUkUser(PamirsSession.getUserCode());
            eamUkHhRow.updateByUnique();
        }


        //若dsMtool.mtool_stat=0时，修改bs_mtool：mtool_stat=1，并记录系统操作日志（略）
        BsMtool mtoolRow = new BsMtool().setOrgCode(orgCode).setMtoolCode(mtoolCode).queryOne();
        if(mtoolRow == null){
            //工装编码：{}在组织编码：{}中未定义。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00004,mtoolCode,orgCode).errThrow();
        }
        if(mtoolRow.getMtoolStat().equals(MtoolStatEnum.NORMAL)){
            mtoolRow.setMtoolStat(MtoolStatEnum.UPKEEP);
            mtoolRow.updateByUnique();
        }
    }

    @Override
    public void beforecompleteMaintain(EamUkHdMtoolReq data) {
        String orgCode = data.getOrgCode();
        String ukCode = data.getUkCode();
        //保养结果值不能为“未知”，否则报错：保养结果值不能为：{0}，请重新输入。；
        int ukRs = data.getUkRs().getValue();
        if(ukRs == UkRsEnum.UNKNOW.getValue()){
            //保养结果值不能为：{0}，请重新输入。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00008,data.getUkRs().getDisplayName()).errThrow();
        }

        //若保养项目明细中的质量状态有“未知“的记录行，报错（只随机提示一行）：保养项目编码：{0}的质量状态为：{1}，不能操作。；
        List<EamUkDtMtoolProxy> ukDtList  = new EamUkDtMtoolProxy().setOrgCode(orgCode).setUkCode(ukCode).queryList();
        List<EamUkDtMtoolProxy> unknowDtList = ukDtList.stream().filter(e-> e.getUkDevStat().equals(UkRsEnum.UNKNOW)).collect(Collectors.toList());
        if(unknowDtList != null && unknowDtList.size()>0){
            EamUkDtMtoolProxy firstUnknowDt = unknowDtList.get(0);
            //保养项目编码：{}的质量状态为：{}，不能操作。
            throw PamirsException.construct(EamExpEnum.EAM_ERROR_00009,firstUnknowDt.getPjCode(),UkDevStatEnum.UNKONW.getDisplayName()).errThrow();
        }

        //若保养项明细的质量状态全部合格或带病作业，主表的保养结果只能为正常，反之为维修/报废，否则报错：所有保养项的质量状态为：{0}，保养结果只能为：{1}。
        long dtGoodCount = ukDtList.stream().filter(e-> UkDevStatEnum.PASS.equals(e.getUkDevStat())
            || UkDevStatEnum.SICK.equals(e.getUkDevStat())).count();
        if(dtGoodCount == ukDtList.size()){
            //全部合格
            if(!UkRsEnum.NORMAL.equals(data.getUkRs())){
                //保养项明细的质量状态全部合格或带病作业，保养结果只能为正常。
                throw PamirsException.construct(EamExpEnum.EAM_ERROR_00010).errThrow();
            }
        } else {
            //有不合格的
            if(UkRsEnum.NORMAL.equals(data.getUkRs())){
                //保养结果只能为{}。
                throw PamirsException.construct(EamExpEnum.EAM_ERROR_00011,UkRsEnum.MAINTAIL.getDisplayName()).errThrow();
            }
        }


        //调用EamCheckUkTime 略过

    }

    @Override
    public EamUkHdMtoolReq completeMaintain(EamUkHdMtoolReq data) {
        EamUkHdMtoolReq result = new EamUkHdMtoolReq();
        String orgCode = data.getOrgCode();
        String ukCode = data.getUkCode();
        String mtoolCode = data.getMtoolCode();
        Date now = new Date();

        //更新保养单
        EamUkHdMtoolProxy updateUkHdRow = new EamUkHdMtoolProxy();
        updateUkHdRow.setOrgCode(orgCode).setUkCode(ukCode);
        updateUkHdRow.setUkRs(data.getUkRs());
        updateUkHdRow.setRkPedate(now);
        updateUkHdRow.setUkStat(UkStatEnum.FINISH);
        updateUkHdRow.setStopTs(data.getStopTs());
        updateUkHdRow.setStopPts(data.getStopPts());
        updateUkHdRow.setIsSick(data.getIsSick());
        updateUkHdRow.updateByUnique();

        //更新工装数据  -- 日志略
        BsMtool updateMtoolRow = new BsMtool();
        updateMtoolRow.setOrgCode(orgCode).setMtoolCode(mtoolCode);
        MtoolStatEnum mtoolStatEnum = MtoolStatEnum.NORMAL;
        if(UkRsEnum.NORMAL.equals(data.getUkRs())){
            mtoolStatEnum = MtoolStatEnum.NORMAL;
        } else if(UkRsEnum.MAINTAIL.equals(data.getUkRs())){
            if(BooleanConstantEnum.Y.equals(data.getIsGenMaintain())){
                mtoolStatEnum = MtoolStatEnum.MAINTAIN;
            } else {
                mtoolStatEnum = MtoolStatEnum.BAD;
            }
        }
        updateMtoolRow.setMtoolStat(mtoolStatEnum);
        updateMtoolRow.setLastUkDate(now);
        updateMtoolRow.setUkUsedTimes(0);
        updateMtoolRow.setIsSick(data.getIsSick());
        updateMtoolRow.updateByUnique();


        //生成维修单 -- 略过

        //生成检验单 -- 略过

        return result;
    }


    @Override
    public Map<String, Object> updateUkDtMaintain(EamUkDtMtoolReq data) {
        String orgCode = data.getOrgCode();
        String ukCode = data.getUkCode();

        //更新保养项
        EamUkDtMtoolProxy updateUkDtRow = new EamUkDtMtoolProxy();
        updateUkDtRow.setOrgCode(orgCode);
        updateUkDtRow.setUkCode(ukCode);
        updateUkDtRow.setSeq(data.getSeq());
        updateUkDtRow.setUkCycType(data.getUkCycType());
        updateUkDtRow.setRvalue(data.getRvalue());
        updateUkDtRow.setUkDevStat(data.getUkDevStat());
        updateUkDtRow.setUkNgCtt(data.getUkNgCtt());
        updateUkDtRow.setUkNgMtd(data.getUkNgMtd());
        updateUkDtRow.setUkDpart(data.getUkDpart());
        updateUkDtRow.setRemark(data.getRemark());
        updateUkDtRow.updateByUnique();

        //处理附件 TODO


        //若有钢网保养张力明细,且保养项类型为张力测试则新增编辑张力测试明细
        if(data.getEamUkDtTensionList() != null && MtoolPjTypeEnum.TENSION.equals(data.getPjType())){
            for(EamUkDtTension dtTension: data.getEamUkDtTensionList()){
                addOrUpdateSingleDtTension(data,dtTension);
            }
        }

        //若有刮刀保养平整度明细,且保养项类型为平整度测试则新增编辑平整度明细
        if(data.getEamUkDtPlanenessList() != null && MtoolPjTypeEnum.PLANENESS.equals(data.getPjType())){
            for(EamUkDtPlaneness dtPlaneness: data.getEamUkDtPlanenessList()){
                addOrUpdateSingleDtPlaneness(data,dtPlaneness);
            }
        }


        return Collections.emptyMap();
    }
    /**
     * 新增编辑单个张力测试明细
     */
    private void addOrUpdateSingleDtTension(EamUkDtMtoolReq data,EamUkDtTension dtTension){
        EamUkDtTension existsRow = new EamUkDtTension();
        existsRow.setOrgCode(dtTension.getOrgCode());
        existsRow.setUkCode(dtTension.getUkCode());
        existsRow.setTensionType(dtTension.getTensionType());
        existsRow = existsRow.queryOne();
        if(existsRow != null){
            existsRow.setTensionValue(dtTension.getTensionValue());
            existsRow.setRemark(dtTension.getRemark());
            existsRow.updateByUnique();
        } else {
            dtTension.create();
        }
    }
    /**
     * 新增编辑单个刮刀平整度明细
     */
    private void addOrUpdateSingleDtPlaneness(EamUkDtMtoolReq data,EamUkDtPlaneness dtPlaneness){
        EamUkDtPlaneness existsRow = new EamUkDtPlaneness();
        existsRow.setOrgCode(dtPlaneness.getOrgCode());
        existsRow.setUkCode(dtPlaneness.getUkCode());
        existsRow.setSeq(dtPlaneness.getSeq());
        existsRow.setPlanenessPoint(dtPlaneness.getPlanenessPoint());
        existsRow = existsRow.queryOne();
        if(existsRow != null){
            existsRow.setPointA(dtPlaneness.getPointA());
            existsRow.setPointB(dtPlaneness.getPointB());
            existsRow.setPointC(dtPlaneness.getPointC());
            existsRow.setPointD(dtPlaneness.getPointD());
            existsRow.setPointE(dtPlaneness.getPointE());
            existsRow.updateByUnique();
        } else {
            dtPlaneness.create();
        }
    }



}


